/* useChatSSE.ts
 * 一个接口同时发消息 + 收 EventStream
 * 支持 H5 / 小程序 / App
 */

import { Params } from "@/api/chat"

export interface ChatMessage { content: string, isMine?: boolean, done: boolean }

type OnMsg = (msg: ChatMessage) => void
type OnErr = (err: any) => void

class ChatSSE {
  private url: string
  private onMsg: OnMsg
  private onErr: OnErr
  private reader: ReadableStreamDefaultReader<Uint8Array> | null = null
  private task: UniApp.RequestTask | null = null
  private decoder = new TextDecoder()

  constructor(opts: { url: string; onMsg: OnMsg; onErr?: OnErr }) {
    // H5 使用 VITE_APP_BASE_API 作为代理路径，其他平台使用 VITE_APP_API_URL 作为请求路径
    let baseApi = import.meta.env.VITE_APP_API_URL;
    // #ifdef H5
    baseApi = import.meta.env.VITE_APP_BASE_API + '/api/web';
    // #endif
    this.url   = `${baseApi}${opts.url}`
    this.onMsg = opts.onMsg
    this.onErr = opts.onErr || (() => {})
  }

  /* 发送消息并建立连接 */
  async send(params: Params) {
    // 1. 本地先渲染
    this.onMsg({
      content: params.question,
      isMine: true,
      done: true
    })

    // 2. 根据平台建立流
    if (typeof window !== 'undefined') {
      // H5 / App-Vue3
      await this._fetch(params)
    } else {
      // 微信小程序
      await this._wx(params)
    }
  }

  /* --- H5 / App --- */
  private async _fetch(params: Params) {
    const res = await fetch(this.url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ...params, token: '123455' })
    })
    this.reader = res.body!.getReader()
    this._pump()
  }

  /* --- 微信小程序 --- */
  private async _wx(params: Params) {
    this.task = uni.request({
      url: this.url,
      method: 'POST',
      data: { ...params, token: '123455' },
      enableChunked: true,
      responseType: 'text'
    })
    this.task.onChunkReceived = ({ data }) => {
      const chunk = this.decoder.decode(new Uint8Array(data))
      this._parse(chunk)
    }
    this.task.onHeadersReceived = () => console.log('连接已建立')
  }

  /* 流式解析 SSE 片段 */
  private _pump() {
    if (!this.reader) return
    this.reader.read().then(({ done, value }) => {
      if (done) {
        this.onMsg({content: '', done})
        return
      }
      const chunk = this.decoder.decode(value, { stream: true })
      this._parse(chunk)
      this._pump()
    }).catch(this.onErr)
  }

  private _parse(chunk: string) {
    chunk
      .split('\n\n')
      .filter(Boolean)
      .forEach(seg => {
        const line = seg.trim()
        if (line.startsWith('data:')) {
          const raw = line.replace(/^data:\s*/, '')
          try {
            const msg: ChatMessage = JSON.parse(raw)
            this.onMsg({content: msg.content, done: false })
          } catch {
            this.onMsg({content: raw, done: false }) // 非 JSON
          }
        }
      })
  }

  /* 关闭连接 */
  close() {
    this.reader?.cancel()
    this.task?.abort()
  }
}

/* 工厂函数 */
export function useChatSSE(opts: { url: string; onMsg: OnMsg; onErr?: OnErr }) {
  return new ChatSSE(opts)
}